const shapefile = require('shapefile');
const fs = require('fs');
const turf = require('turf');

// 读取配置文件
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'));

// 颜色配置
const LAND_COLOR = config.landColor || "#978172";
const COORDINATE_PRECISION = config.coordinatePrecision || 6;

/**
 * 使用斐波那契球面采样算法生成在球面上均匀分布的点
 * 这种方法确保极地和赤道附近的点密度基本相同
 * @param {number} numPoints - 要生成的点数
 * @returns {Array} 包含球面坐标点的数组
 */
function generateFibonacciSpherePoints(numPoints) {
    const points = [];
    const goldenRatio = (1 + Math.sqrt(5)) / 2;

    for (let i = 0; i < numPoints; i++) {
        // 计算球面坐标
        const y = 1 - (i / (numPoints - 1)) * 2; // y从1到-1
        const radius = Math.sqrt(1 - y * y);

        const theta = 2 * Math.PI * i / goldenRatio;

        const x = Math.cos(theta) * radius;
        const z = Math.sin(theta) * radius;

        // 转换为经纬度
        const lat = Math.asin(y) * 180 / Math.PI;
        const lng = Math.atan2(z, x) * 180 / Math.PI;

        points.push({ x, y, z, lng, lat });
    }

    return points;
}

/**
 * 主函数：生成地球陆地点阵数据
 */
async function generatePoints() {
    try {
        console.log('🌍 开始读取Natural Earth shapefile数据...');

        // 读取shapefile
        const source = await shapefile.open('ne_10m_land.shp');

        const features = [];

        // 读取所有要素
        let result;
        while (result = await source.read(), !result.done) {
            features.push(result.value);
        }

        console.log(`✅ 成功读取了 ${features.length} 个陆地多边形`);

        // 根据密度配置计算需要生成的球面点数
        const basePoints = 40000; // 基础点数
        const numPoints = Math.floor(basePoints * config.pointDensity);
        console.log(`📊 生成 ${numPoints} 个球面均匀分布点 (密度系数: ${config.pointDensity})...`);

        const spherePoints = generateFibonacciSpherePoints(numPoints);
        const landPoints = [];

        console.log('🔍 筛选落在陆地上的点...');

        // 筛选落在陆地上的点
        let processed = 0;
        const totalPoints = spherePoints.length;
        const progressInterval = Math.floor(totalPoints / 10); // 每10%显示一次进度

        for (const point of spherePoints) {
            processed++;

            // 显示进度
            if (processed % progressInterval === 0) {
                const progress = Math.floor((processed / totalPoints) * 100);
                console.log(`⏳ 处理进度: ${progress}%`);
            }

            const turfPoint = turf.point([point.lng, point.lat]);

            // 检查点是否在任何一个陆地多边形内
            for (const feature of features) {
                if (turf.inside(turfPoint, feature)) {
                    landPoints.push({
                        lng: parseFloat(point.lng.toFixed(COORDINATE_PRECISION)),
                        lat: parseFloat(point.lat.toFixed(COORDINATE_PRECISION)),
                        color: LAND_COLOR
                    });
                    break;
                }
            }
        }

        console.log(`✅ 成功生成 ${landPoints.length} 个陆地点数据`);

        // 保存为JSON文件
        fs.writeFileSync(config.outputFile, JSON.stringify(landPoints, null, 2));
        console.log(`💾 数据已保存到 ${config.outputFile}`);

        // 显示统计信息
        console.log('\n📈 生成统计:');
        console.log(`   总点数: ${landPoints.length}`);
        console.log(`   陆地比例: ${((landPoints.length / numPoints) * 100).toFixed(2)}%`);
        console.log(`   颜色代码: ${LAND_COLOR}`);
        console.log(`   坐标精度: ${COORDINATE_PRECISION} 位小数`);

    } catch (error) {
        console.error('❌ 处理过程中发生错误:', error);
        process.exit(1);
    }
}

// 执行生成函数
generatePoints();